/**
 * Copyright 2010 Adam Ruggles.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package saig.engine.editors;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;

import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

import saig.engine.Level;
import saig.engine.models.Model;
import saig.engine.models.Tile;
import saig.engine.resources.TileLoader;
import saig.engine.utils.LevelUtil;


/**
 * The Game Map Editor.
 * @author Adam
 * @version $Id$
 * 
 * Created on Jun 14, 2010 at 8:24:44 PM 
 */
public class MapEditor extends JFrame {
	/**
	 * Serial Version UID.
	 */
	private static final long serialVersionUID = 1363235047664194594L;
	/**
	 * The title of the map editor.
	 */
	private static final String TITLE = "SAIG Map Editor";
	/**
	 * Launches the Map Editor.
	 * @param args Command line arguments, not currently supported.
	 * @throws UnsupportedLookAndFeelException 
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 * @throws ClassNotFoundException 
	 */
	public static void main(final String[] args) throws ClassNotFoundException, InstantiationException,
		IllegalAccessException, UnsupportedLookAndFeelException {
		UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				final MapEditor mapEditor = new MapEditor();
				mapEditor.setLocationRelativeTo(null);
				mapEditor.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				mapEditor.setVisible(true);
			}
		});
	}
	/**
	 * The main content pane.
	 */
	private JPanel contentPane = null;
	/**
	 * Used to select files to save and load.
	 */
	private JFileChooser fileChooser;
	/**
	 * The level pane, used for editing the level.
	 */
	private LevelPane levelPane = null;
	/**
	 * The map/level scroll pane.
	 */
	private JScrollPane mapScrollPane = null;
	/**
	 * The menu bar.
	 */
	private JMenuBar menuBar = null;
	/**
	 * The selectable pane.
	 */
	private SelectorPane selectorPane = null;
	/**
	 * The split pane, used to divide the into a flexible nav and content window.
	 */
	private JSplitPane splitPane = null;
	/**
	 * The tile selection scroll pane. 
	 */
	private JScrollPane tileScrollPane = null;
	/**
	 * Default Constructor.
	 */
	public MapEditor() {
		super();
		initialize();
	}
	/**
	 * Returns the active pane in the selector pane.
	 * @return The active pane in the selector pane.
	 */
	public int getActiveSelectorPane() {
		return selectorPane.getActivePane();
	}
	/**
	 * Returns the menu bar for the map editor.
	 * @return The menu bar for the map editor.
	 */
	private JMenuBar getMapMenuBar() {
		if (menuBar == null) {
			menuBar = new JMenuBar();
			// Create the file chooser.
			fileChooser = new JFileChooser();
			// The file menu.
			final JMenu fileMenu = new JMenu();
			fileMenu.setText("File");
			fileMenu.setMnemonic(KeyEvent.VK_F);
			menuBar.add(fileMenu);
			// The tools menu.
			final JMenu toolsMenu = new JMenu();
			toolsMenu.setText("Tools");
			toolsMenu.setMnemonic(KeyEvent.VK_T);
			menuBar.add(toolsMenu);
			// File Menu Items
			JMenuItem openItem = new JMenuItem("Open File...");
			openItem.setMnemonic(KeyEvent.VK_O);
			fileMenu.add(openItem);
			openItem.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					if (fileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
						Level level = LevelUtil.loadLevel(fileChooser.getSelectedFile());
						if (level != null) {
							level.setShowGrid(levelPane.getLevel().isShowGrid());
							levelPane.setLevel(level);
						}
					}
				}
			});
			JMenuItem saveItem = new JMenuItem("Save");
			saveItem.setMnemonic(KeyEvent.VK_S);
			fileMenu.add(saveItem);
			saveItem.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					if (fileChooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) {
						LevelUtil.saveLevel(fileChooser.getSelectedFile(), levelPane.getLevel());
					}
				}
			});
			// Tools Menu Items.
			JCheckBoxMenuItem gridSwitchMenuItem = new JCheckBoxMenuItem("Show Grid");
			gridSwitchMenuItem.setSelected(true);
			gridSwitchMenuItem.setMnemonic(KeyEvent.VK_G);
			toolsMenu.add(gridSwitchMenuItem);
			gridSwitchMenuItem.addItemListener(new ItemListener() {
				public void itemStateChanged(final ItemEvent e) {
					if (e.getStateChange() == ItemEvent.SELECTED) {
						levelPane.getLevel().setShowGrid(true);
					} else {
						levelPane.getLevel().setShowGrid(false);
					}
				}
			});
			// Set the menu bar.
			setJMenuBar(menuBar);
		}
		return menuBar;
		
	}
	/**
	 * Returns the selected model.
	 * @return The selected model.
	 */
	public Model getSelectedModel() {
		return selectorPane.getSelectedModel();
	}
	/**
	 * Returns the selected tile.
	 * @return The selected tile.
	 */
	public Tile getSelectedTile() {
		return selectorPane.getSelectedTile();
	}
	/**
	 * Initializes all the map editor elements.
	 */
	private void initialize() {
		setSize(800, 600);
		setTitle(TITLE);
		getMapMenuBar();
		// Create the content pane.
		contentPane = new JPanel();
		contentPane.setLayout(new BorderLayout());
		setContentPane(contentPane);
		// Create the split pane.
		splitPane = new JSplitPane();
		contentPane.add(splitPane, BorderLayout.CENTER);
		// Create the selector pane.
		selectorPane = new SelectorPane();
		// Create the level pane.
		final Level level = new Level(320, 15, TileLoader.getInstance().getTileWidth(),
				TileLoader.getInstance().getTileHeight());
		level.setShowGrid(true);
		levelPane = new LevelPane(level, this);
		// Create the scroll panes.
		tileScrollPane = new JScrollPane(selectorPane);
		mapScrollPane = new JScrollPane(levelPane);
		levelPane.setViewport(mapScrollPane.getViewport());
		tileScrollPane.setMinimumSize(new Dimension(150, 400));
		mapScrollPane.setMinimumSize(new Dimension(200, 400));
		splitPane.setLeftComponent(tileScrollPane);
		splitPane.setRightComponent(mapScrollPane);
		// Repaint the level pane for animation.
		final ActionListener repainter = new ActionListener() {
			public void actionPerformed(final ActionEvent e) {
				levelPane.repaint();
				for (Tile tile : TileLoader.getInstance().getTiles()) {
					tile.advanceFrame();
				}
			}
		};
		new Timer(150, repainter).start();
	}
}
